package com.hong.filter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.hong.common.AjaxResultVo;
import com.hong.common.util.HttpUtil;
import com.hong.common.util.ShiroUtil;

public class LoginFilter extends AccessControlFilter {

	private static final Logger logger = LoggerFactory.getLogger(LoginFilter.class);

	@Override
	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
		if (isLoginRequest(request, response)) {
			return true;
		} else {
			Subject subject = getSubject(request, response);
			return subject.getPrincipal() != null;
		}
	}

	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		HttpServletResponse httpServletResponse = (HttpServletResponse) response;
		if (HttpUtil.isAjax(httpServletRequest)) {
			logger.debug("当前用户没有登录，并且是Ajax请求!");
			httpServletResponse.setHeader("sessionstatus", "timeout");
			AjaxResultVo timeout = AjaxResultVo.error("401", "登录超时，请重新登录");
			HttpUtil.write(httpServletResponse, JSONObject.toJSONString(timeout));
			return false;
		} else {
			String referer = httpServletRequest.getHeader("Referer");
			if (referer == null) {
				saveRequestAndRedirectToLogin(request, response);
				return false;
			} else {
				if (ObjectUtils.isEmpty(ShiroUtil.getSessionAttribute("sessionFlag"))) {
					httpServletRequest.setAttribute("errorMsg", "登录超时，请重新登录");
					httpServletRequest.getRequestDispatcher("/login").forward(request, response);
					return false;
				} else {
					saveRequestAndRedirectToLogin(request, response);
					return false;
				}
			}
		}
	}
}